using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace BLT
{    
    public class Level
    {
        #region Fields/Getters and Setters
        /// <summary>
        /// The background image's texture
        /// </summary>
        public Texture2D m_background {
            get { return background; }
            set { background = value; }
        }
        private Texture2D background;

        /// <summary>
        /// The background scrolling horizontal variable
        /// </summary>
        public bool m_isRightScrolling
        {
            get { return isRightScrolling; }
            set { isRightScrolling = value; }
        }
        private bool isRightScrolling;

        /// <summary>
        /// The background scrolling verticle variable
        /// </summary>
        public bool m_isUpScrolling
        {
            get { return isUpScrolling; }
            set { isUpScrolling = value; }
        }
        private bool isUpScrolling;

        /// <summary>
        /// The background horizontal scrolling speed
        /// </summary>
        public int m_xScrollSpeed
        {
            get { return xScrollSpeed; }
            set { xScrollSpeed = value; }
        }
        private int xScrollSpeed;

        /// <summary>
        /// The background horizontal scrolling speed
        /// </summary>
        public int m_yScrollSpeed
        {
            get { return yScrollSpeed; }
            set { yScrollSpeed = value; }
        }
        private int yScrollSpeed;

        /// <summary>
        /// The collection of Sprites in a level, represented as a List of Sprite Objects
        /// </summary>
        public List<Sprite> m_spriteCollection {
            get { return spriteCollection; }
            set { spriteCollection = value; }
        }
        private List<Sprite> spriteCollection = new List<Sprite>();

        /// <summary>
        /// This sets a force to be associated with the sprites
        /// </summary>
        public Vector2 m_force {
            get { return force; }
            set { force = value; }
        }
        private Vector2 force = new Vector2(0, 0);

        /// <summary>
        /// This allows the screen height to be set
        /// </summary>
        public Rectangle m_viewableArea {
            get { return viewableArea; }
            set { viewableArea = value; }
        }
        private Rectangle viewableArea = new Rectangle(0, 0, 0, 0);        

        /// <summary>
        /// This may be used to set the background color (behind the background image)
        /// </summary>
        public Color m_backgroundColor {
            get { return backgroundColor; }
            set { backgroundColor = value; }
        }
        private Color backgroundColor = new Color();
        #endregion

        #region Constructors
        public Level( Texture2D pbackground, Color pbackgroundColor ) {
            background = pbackground;
            backgroundColor = pbackgroundColor;
            viewableArea.Equals(new Rectangle(0, 0, 800, 600));
        }

        public Level( Texture2D pbackground, Color pbackgroundColor, Rectangle pviewableArea ) 
        {
            background = pbackground;
            backgroundColor = pbackgroundColor;
            viewableArea.Equals(pviewableArea);
        }

        public Level( Texture2D pbackground, Color pbackgroundColor, Rectangle pviewableArea, Vector2 pforce )
            : this(pbackground, pbackgroundColor, pviewableArea) 
        {
            force = pforce;
        }

        public Level( Texture2D pbackground, Color pbackgroundColor, Rectangle pviewableArea, Vector2 pforce, List<Sprite> pspriteCollection )
            : this(pbackground, pbackgroundColor, pviewableArea, pforce) 
        {
            spriteCollection = pspriteCollection;
        }
        #endregion

        #region All other Functions
        /// <summary>
        /// Updates the background image if it is meant to scroll and also updates the Sprite positions
        /// (by calling the Update method of each sprite).
        /// </summary>
        public void Update( GameTime gameTime ) {
            //TO DO: implement scrolling
            //TO DO: possibly do something with the global force variable
            for (int i = 0; i < spriteCollection.Count; i++)
            {
                spriteCollection[i].Update(gameTime, true, true);
            }
        }

        /// <summary>
        /// Draws the visible portion of the background and all the sprites within the visible portion
        /// </summary>
        public void Draw( SpriteBatch spriteBatch ) {
            spriteBatch.Draw(background, Vector2.Zero, backgroundColor);
            for (int i = 0; i < spriteCollection.Count; i++)
            {
                spriteCollection[i].Draw(spriteBatch);
            }
        }

        /// <summary>
        /// Adds the given force vector to each Sprite's current forces within the Sprite collection
        /// (simply scrolls through sprite collection and calls their AddForce function)
        /// </summary>
        public void AddForce( Vector2 force ) {
            for (int i = 0; i < spriteCollection.Count; i++){
                spriteCollection[i].AddForce(force);
            }
        }

        /// <summary>
        /// Sets the size and location of the viewable area (in pixels)
        /// </summary>
        public void SetViewableArea( int x, int y, int width, int height ) {
            viewableArea.Equals(new Rectangle(x, y, width, height));
        }

        /// <summary>
        /// Sets the size and location of the viewable area (in pixels)
        /// </summary>
        public void SetViewableArea(Rectangle rect) {
            viewableArea.Equals(rect);
        }

        /// <summary>
        /// Moves the viewable area (use negative numbers to go backward)
        /// </summary>
        public void MoveViewableArea( int xAmount, int yAmount ) {
            viewableArea.X += xAmount;
            viewableArea.Y += yAmount;
        }

        /// <summary>
        /// Adds a Sprite to this level's Sprite Collection
        /// </summary>
        public void AddSprite(Sprite sprite) {
            spriteCollection.Add(sprite);
        }

        /// <summary>
        /// Removes a Sprite from this level's Sprite Collection
        /// </summary>
        public void RemoveSprite(Sprite sprite) {
            if (spriteCollection.Contains(sprite)){
                spriteCollection.Remove(sprite);
            }
        }

        /// <summary>
        /// Iterate through all the sprites, check if any are colliding, and run their doCollision()
        /// </summary>
        public void doAllCollisions() {
            for (int i = 0; i < spriteCollection.Count; i++)
            {
                for (int j = 0; j < spriteCollection.Count; j++){
                    if (i != j){
                        if (spriteCollection[i].CollidesWith(spriteCollection[j].m_boundingBox)){
                            spriteCollection[i].doCollision(spriteCollection[j]);
                        }
                    }
                }
            }
        }
        #endregion

    }
}
